#include "stdafx.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif
/////////////////////////////////////////////////////////////////////////////////////////////////
void GetExtremum(long lOffset,long lData,double*fLow,double*fHigh,double*pcdHigh,double*pcdLow)
{
	long i=max(0,lOffset-lData+1);
	*fHigh=pcdHigh[i];
	*fLow=pcdLow[i];
	for(++i;i<=lOffset;++i)
	{
		if(pcdHigh[i]>*fHigh) *fHigh = pcdHigh[i];
		if(pcdLow[i]<*fLow) *fLow = pcdLow[i];
	}
}

void calc_kdj(tagUMyCalcFormula*pFormula,long numCalc,phistory_data paData,double*dataCalc[10],long decNum,long sec_type,_procReflection procReflection)
{
	long param1 = pFormula->infoParam[0].nowValue;
	long param2 = pFormula->infoParam[1].nowValue;
	long param3 = pFormula->infoParam[2].nowValue;
	if(param1<2||param2<1||param1>numCalc+1)
	{
	}
	else
	{
		double *K=dataCalc[0],*D=dataCalc[1],*J=dataCalc[2];
		double *RSV=dataCalc[3],theLow=0,theHigh=1;
		double*pcdHigh=dataCalc[6],*pcdLow=dataCalc[7];
		double seedPrice(__price_seed__[decNum]);
		long i=0,j=0;
		for(i=0;i<numCalc;++i)
		{
			pcdHigh[i] = paData[i].highPx/seedPrice;
			pcdLow[i] = paData[i].lowPx/seedPrice;
		}
		for(i=0;i<numCalc;++i)
		{
			GetExtremum(i,param1,&theLow,&theHigh,pcdHigh,pcdLow);
			RSV[i] = fabs(theHigh-theLow)<0.000001?50:
				(paData[i].ClosePx/seedPrice-theLow)/max(theHigh-theLow,0.0001)*100;
		}
		for(i=j+1,K[j]=D[j]=J[j]=50;i<numCalc;i++)
		{
			K[i] = (K[i-1]*(param2-1)+RSV[i])/param2;
			D[i] = (K[i]+(param3-1)*D[i-1])/param3;
			J[i] = 3*K[i] - 2*D[i];
		}
	}
}
/*
RSV:=(CLOSE-LLV(LOW,N))/(HHV(HIGH,N)-LLV(LOW,N))*100;
K:SMA(RSV,M1,1);
D:SMA(K,M2,1);
J:3*K-2*D;
*/

void calc_skdj(tagUMyCalcFormula*pFormula,long numCalc,phistory_data paData,double*dataCalc[10],long decNum,long sec_type,_procReflection procReflection)
{
	long i=0;
	double*LOWV=dataCalc[5],*HIGHV=dataCalc[4];
	double*RSV=dataCalc[3],varData=0;
	double*K=dataCalc[0],*D=dataCalc[1];
	double*pcdHigh=dataCalc[6],*pcdLow=dataCalc[7];
	double seedPrice(__price_seed__[decNum]);

	for(i=0;i<numCalc;++i)
	{
		pcdHigh[i] = paData[i].highPx/seedPrice;
		pcdLow[i] = paData[i].lowPx/seedPrice;
	}

	UMyCalc_LLV(LOWV,pcdLow,numCalc,pFormula->infoParam[0].nowValue);
	UMyCalc_HHV(HIGHV,pcdHigh,numCalc,pFormula->infoParam[0].nowValue);

	for(i=0;i<numCalc&&(UMyCalc_invalid(LOWV[i])||UMyCalc_invalid(HIGHV[i]));++i);
	for(;i<numCalc;++i)
	{
		if(fabs(varData=HIGHV[i]-LOWV[i])<0.000001)
		{
			if(i) RSV[i] = RSV[i-1];
		}
		else
		{
			RSV[i] = (paData[i].ClosePx/seedPrice-LOWV[i])/varData*100;
		}
	}
	UMyCalc_EMA(RSV,numCalc,pFormula->infoParam[1].nowValue);
	memcpy(K,RSV,numCalc*sizeof(double));
	UMyCalc_EMA(K,numCalc,pFormula->infoParam[1].nowValue);
	memcpy(D,K,numCalc*sizeof(double));
	UMyCalc_MA(D,numCalc,pFormula->infoParam[1].nowValue);
}
/*
LOWV:=LLV(LOW,N);
HIGHV:=HHV(HIGH,N);
RSV:=EMA((CLOSE-LOWV)/(HIGHV-LOWV)*100,M);
K:EMA(RSV,M);
D:MA(K,M);
*/

void calc_faststo(tagUMyCalcFormula*pFormula,long numCalc,phistory_data paData,double*dataCalc[10],long decNum,long sec_type,_procReflection procReflection)
{
	long param1 = pFormula->infoParam[0].nowValue;
	long param2 = pFormula->infoParam[1].nowValue;
	if(param1<2||param1>numCalc+1)
	{
	}
	else
	{
		double *K=dataCalc[0],theLow=0,theHigh=1;
		double*pcdHigh=dataCalc[6],*pcdLow=dataCalc[7];
		double seedPrice(__price_seed__[decNum]);
		long i(0),j(0);
		for(i=0;i<numCalc;++i)
		{
			pcdHigh[i] = paData[i].highPx/seedPrice;
			pcdLow[i] = paData[i].lowPx/seedPrice;
		}
		for(i=0,j=param1-2;i<numCalc;++i)
		{
			GetExtremum(i,param1,&theLow,&theHigh,pcdHigh,pcdLow);
			K[i] = fabs(theHigh-theLow)<0.000001?50:
				(paData[i].ClosePx/seedPrice-theLow)/max(theHigh-theLow,0.0001)*100;
		}
		memcpy(dataCalc[1],K,numCalc*sizeof(double));
		UMyCalc_MA(dataCalc[1],numCalc,param2);
	}
}
